package cn.itcast.web.controller.cargo;

import cn.itcast.domain.cargo.*;
import cn.itcast.domain.system.User;
import cn.itcast.service.cargo.ContractService;
import cn.itcast.service.cargo.ExportProductService;
import cn.itcast.service.cargo.ExportService;
import cn.itcast.vo.ExportProductVo;
import cn.itcast.vo.ExportResult;
import cn.itcast.vo.ExportVo;
import cn.itcast.web.controller.BaseController;
import cn.itcast.web.utils.BeanMapUtils;
import com.alibaba.dubbo.config.annotation.Reference;
import com.github.pagehelper.PageInfo;
import net.sf.jasperreports.engine.JREmptyDataSource;
import net.sf.jasperreports.engine.JasperExportManager;
import net.sf.jasperreports.engine.JasperFillManager;
import net.sf.jasperreports.engine.JasperPrint;
import net.sf.jasperreports.engine.data.JRBeanCollectionDataSource;
import org.apache.cxf.jaxrs.client.WebClient;
import org.bouncycastle.util.Strings;
import org.springframework.beans.BeanUtils;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.cglib.beans.BeanMap;
import org.springframework.stereotype.Controller;
import org.springframework.util.StringUtils;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.RequestParam;
import org.springframework.web.bind.annotation.ResponseBody;
import sun.invoke.empty.Empty;

import javax.sql.DataSource;
import java.io.InputStream;
import java.lang.reflect.InvocationTargetException;
import java.util.*;

@Controller
@RequestMapping("/cargo/export")
public class ExportController extends BaseController{

    @Reference(check = false,retries = 0)
    private ContractService contractService;

    @Reference(check = false,retries = 0)
    private ExportService exportService;

    @Reference(check = false,retries = 0)
    private ExportProductService exportProductService;

    /*
        作用： 进入合同列表页面
        url： /cargo/export/contractList.do
        参数： 无
        返回值： cargo/export/export-contractList
     */
    @RequestMapping("/contractList")
    public String contractList(@RequestParam(defaultValue = "1") Integer pageNum, @RequestParam(defaultValue = "5") Integer pageSize){
        ContractExample contractExample = new ContractExample();
        //添加条件
        contractExample.createCriteria().andStateEqualTo(1).andCompanyIdEqualTo(getLoginCompanyId());
        //根据创建的时间排序
        contractExample.setOrderByClause("create_time desc");

        PageInfo<Contract> pageInfo = contractService.findByPage(contractExample, pageNum, pageSize);
        request.setAttribute("pageInfo",pageInfo);
        return "cargo/export/export-contractList";
    }


    /*
        作用： 进入报运单列表页面
        url： /cargo/export/list.do
        参数： 无
        返回值： cargo/export/export-list
     */
    @RequestMapping("/list")
    public String list(@RequestParam(defaultValue = "1") Integer pageNum, @RequestParam(defaultValue = "5") Integer pageSize){
        //找到所有报运单
        ExportExample exportExample = new ExportExample();
        exportExample.setOrderByClause("create_time desc");
        exportExample.createCriteria().andCompanyIdEqualTo(getLoginCompanyId());
        PageInfo<Export> pageInfo = exportService.findByPage(exportExample, pageNum, pageSize);
        request.setAttribute("pageInfo",pageInfo);
        return "cargo/export/export-list";
    }

    /*
    作用： 进入生成报运单的页面
    url： /cargo/export/toExport.do
    参数： 选中的报运单的id
    返回值： cargo/export/export-toExport
 */
    @RequestMapping("/toExport")
    public String toExport(String id){// 格式：1,2
        request.setAttribute("id",id);
        return "cargo/export/export-toExport";
    }


    /*
     作用： 保存添加与修改报运单
     路径： /cargo/export/edit.do
     参数： 报运单
     返回值：报运单列表
    */
    @RequestMapping("/edit")
    public String edit(Export export){
        //1. 给报运单补充企业的id与企业名称
        String companyId = getLoginCompanyId();
        String companyName = getLoginCompanyName();
        export.setCompanyId(companyId);
        export.setCompanyName(companyName);
        //报运单的创建人
        export.setCreateBy(getLoginUser().getId());
        //报运单创建人所属部门
        export.setCreateDept(getLoginUser().getDeptId());

        //2.根据报运单的id判断是否是增加还是修改
        if(StringUtils.isEmpty(export.getId())){
            //添加
            exportService.save(export);
        }else{
            //修改
            exportService.update(export);
        }
        //3. 返回报运单的列表页面
        return "redirect:/cargo/export/list.do";
    }


    /*
    作用： 进入报运单修改页面
    路径：/cargo/export/toUpdate.do?id=26121e37-9e05-4167-8be7-f8675f8dcab6
    参数： 报运单id
    返回值：cargo/export/export-update
   */
    @RequestMapping("/toUpdate")
    public String toUpdate(String id){
        //找到报运单
        Export export = exportService.findById(id);
        request.setAttribute("export",export);
        //找到报运单下面的商品
        ExportProductExample exportProductExample = new ExportProductExample();
        exportProductExample.createCriteria().andExportIdEqualTo(id);
        List<ExportProduct> exportProductList = exportProductService.findAll(exportProductExample);
        request.setAttribute("eps",exportProductList);
        return "cargo/export/export-update";

    }


    /*
   作用： 查看报运单
   路径：/cargo/export/toView.do?id=26121e37-9e05-4167-8be7-f8675f8dcab6
   参数： 报运单id
   返回值：cargo/export/export-view
  */
    @RequestMapping("/toView")
    public String toView(String id){
        Export export = exportService.findById(id);
        request.setAttribute("export",export);
        return "cargo/export/export-view";
    }


    /*
        作用： 提交报运单
        路径：/cargo/export/submit.do?id=26121e37-9e05-4167-8be7-f8675f8dcab6
        参数： 报运单id
        返回值：报运单列表
    */
    @RequestMapping("/submit")
    public String submit(String id){
        Export export = exportService.findById(id);
        ExportProductExample exportProductExample = new ExportProductExample();
        exportProductExample.createCriteria().andExportIdEqualTo(export.getId());
        List<ExportProduct> exportProducts = exportProductService.findAll(exportProductExample);
        for (ExportProduct exportProduct : exportProducts) {
            Double sizeHeight = exportProduct.getSizeHeight();
            Double sizeWidth = exportProduct.getSizeWidth();
            Double sizeLength = exportProduct.getSizeLength();
            Integer cnumber = exportProduct.getCnumber();
            Double grossWeight = exportProduct.getGrossWeight();
            Double netWeight = exportProduct.getNetWeight();
            Double exPrice = exportProduct.getExPrice();
            if (StringUtils.isEmpty(sizeHeight)||
                    StringUtils.isEmpty(sizeWidth)||
                    StringUtils.isEmpty(sizeLength)||
                    StringUtils.isEmpty(cnumber)||
                    StringUtils.isEmpty(grossWeight)||
                    StringUtils.isEmpty(netWeight)||
                    StringUtils.isEmpty(exPrice)){
                //空就直接不修改数据库，直接跳转集合页面
                return "redirect:/cargo/export/list.do";
            }
        }
        //设置状态
        export.setState(1);
        Double totalVolume = 0.0;      //总体积
        Double grossWeights = 0.0;     //总毛重
        PackingList packingList = new PackingList();
            //报运合同号的结合成的字符串；
                for (ExportProduct exportProduct : exportProducts) {
                    //体积=报运货物的长*宽*高*个数
                    totalVolume += exportProduct.getSizeHeight() * exportProduct.getSizeWidth() * exportProduct.getSizeHeight() * exportProduct.getCnumber();
                    //毛重=
                    grossWeights += exportProduct.getGrossWeight() * exportProduct.getCnumber();

                }
        //加入 总体积  总毛重
        export.setMeasurements(totalVolume);
        export.setGrossWeights(grossWeights);
        //更新报运单
        exportService.update(export);
        return "redirect:/cargo/export/list.do";
    }


    /*
      作用： 取消报运单
      路径：/cargo/export/cancel.do?id=26121e37-9e05-4167-8be7-f8675f8dcab6
      参数： 报运单id
      返回值：报运单列表
  */
    @RequestMapping("/cancel")
    public String cancel(String id){
        Export export = exportService.findById(id);
        //设置状态
        export.setState(0);
        //更新报运单
        exportService.update(export);
        return "redirect:/cargo/export/list.do";
    }

    /*
        作用： 电子报运
        路径：/cargo/export/exportE.do?id=26121e37-9e05-4167-8be7-f8675f8dcab6
        参数： 报运单id
        返回值：报运单列表
    */
    @RequestMapping("/exportE")
    public String exportE(String id) throws Exception {
        //1. 根据id找到对应的报运单 Export对象
        Export export = exportService.findById(id);

        //2.创建ExportVo对象，目标是把Export的数据复制到ExportVo对象，因为需要与海关实体类一致
        ExportVo exportVo = new ExportVo();
        //属性数据拷贝
        BeanUtils.copyProperties(export,exportVo);
        //补充数据
        exportVo.setExportId(export.getId());


        //3. 找到报运单对应的商品的数据
        ExportProductExample exportProductExample = new ExportProductExample();
        exportProductExample.createCriteria().andExportIdEqualTo(id);
        List<ExportProduct> productList = exportProductService.findAll(exportProductExample);

        //4. 需要把商品的数据转换为ExportProductVo对象
        for (ExportProduct exportProduct : productList) {
            //每一个报运单的商品就对应一个ExportProductVo
            ExportProductVo exportProductVo = new ExportProductVo();
            //拷贝属性
            BeanUtils.copyProperties(exportProduct,exportProductVo);
            //补充数据
            exportProductVo.setExportId(export.getId());
            //商品的id
            exportProductVo.setExportProductId(exportProduct.getId());
            //把exportProductVO对象添加到ExportVo对象
            exportVo.getProducts().add(exportProductVo);
        }

        //5. 把ExportVo对象通过WebService提交给海关
        WebClient.create("http://192.168.110.129:8080/jk_export/ws/export/user").post(exportVo);
        Thread.sleep(1000*10);
        //6. 查看报运单的审核结果
        ExportResult exportResult = WebClient.create("http://192.168.110.129:8080/jk_export/ws/export/user/" + id).get(ExportResult.class);


        //7. 根据海关的审核结果更新报运单的信息
        exportService.updateState(exportResult);

        return "redirect:/cargo/export/list.do";
    }


    @Autowired
    private DataSource dataSource;

    /*
     作用： 下载电子 报运单
     路径：/cargo/export/exportPdf.do?id=26121e37-9e05-4167-8be7-f8675f8dcab6
     参数： 报运单id
     返回值：没有，下载
     */
    @RequestMapping("/exportPdf")
    @ResponseBody
    public void exportPdf(String id) throws Exception {
        //设置响应头
        response.setHeader("content-disposition","attachment;filename=export.pdf");

        //1. 读取模板
        InputStream inputStream = session.getServletContext().getResourceAsStream("/jasper/export.jasper");

        //2. 将模板与数据结合得到JasperPrint对象
        /*
            fillReport(InputStream inputStream, Map<String, Object> parameters, JRDataSource dataSource)
                    inputStream: 模板的输入流
                    parameters: 不需要遍历参数，填充的参数
                    dataSource: 需要遍历的集合数据存储到数据源
         */

        //3. 根据id查找到报运单
        Export export = exportService.findById(id);

        //4. 把export对象转换为map
        Map<String, Object> map = BeanMapUtils.beanToMap(export);

        //5. 查找报运商品
        ExportProductExample exportProductExample = new ExportProductExample();
        exportProductExample.createCriteria().andExportIdEqualTo(id);
        List<ExportProduct> productList = exportProductService.findAll(exportProductExample);

        //把list集合的数据交给数据源
        JRBeanCollectionDataSource dataSource = new JRBeanCollectionDataSource(productList);

        JasperPrint jasperPrint = JasperFillManager.fillReport(inputStream,map,dataSource);

        //3. 把pdf输出
        JasperExportManager.exportReportToPdfStream(jasperPrint,response.getOutputStream());
    }

    /*
            作用：删除
            路径：
            参数：
            返回值：
        */
        @RequestMapping("/delete")
        public String methodName(String id){
        exportService.delete(id);
            return "redirect:/cargo/export/list.do";


     }


}
